package com.probiz.estore.solrsearch.service.impl;


import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrServer;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.impl.CommonsHttpSolrServer;
import org.apache.solr.client.solrj.request.QueryRequest;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.client.solrj.response.UpdateResponse;
import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.SolrDocumentList;
import org.apache.solr.common.params.CommonParams;
import org.apache.solr.common.params.HighlightParams;

import com.probiz.estore.common.helper.ConfigUtil;
import com.probiz.estore.common.model.content.Content;
import com.probiz.estore.common.model.product.Product;
import com.probiz.estore.content.service.ContentManager;
import com.probiz.estore.core.event.EventUtil;
import com.probiz.estore.core.search.SearchCriteria;
import com.probiz.estore.product.service.ProductManager;
import com.probiz.estore.solrsearch.model.IndexEntity;
import com.probiz.estore.solrsearch.model.SolrSearchCriteria;
import com.probiz.estore.solrsearch.service.SolrSearchService;
import com.probiz.estore.webapp.event.SolrIndexRefreshEvent;

public class SolrSearchServiceImpl implements SolrSearchService {
    
	private static Log log = LogFactory.getLog(SolrSearchServiceImpl.class);
	public final static String FULL_IMPORT  =  "full-import";
	public final static String DELTA_IMPORT = "delta-import";
	
	private ContentManager contentManager;
	private ProductManager productManager;
	
	public void setContentManager(ContentManager contentManager) {
		this.contentManager = contentManager;
	}
	public void setProductManager(ProductManager productManager) {
		this.productManager = productManager;
	}
	/*
	 * (non-Javadoc)
	 * @see com.probiz.estore.solrsearch.service.SolrSearchService#buildDeltaIndex()
	 */
	public int buildDeltaIndex() {
		if(ConfigUtil.getInstance().isOpenFulltextSearch()){
			return excuteSolrCommand(DELTA_IMPORT);
		}
		return 500;
	}
	/*
	 * (non-Javadoc)
	 * @see com.probiz.estore.solrsearch.service.SolrSearchService#buildFullIndex()
	 */
	public int buildFullIndex() {
		return excuteSolrCommand(FULL_IMPORT);
	}
	/*
	 * (non-Javadoc)
	 * @see com.probiz.estore.solrsearch.service.SolrSearchService#deleteIndex(java.lang.String)
	 */
	public void deleteIndex(String pk){
		try {
			UpdateResponse updateResponse = this.getSolrServer().deleteById(pk);
			this.getSolrServer().commit();
		} catch (SolrServerException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch(Exception e){
			e.printStackTrace();
		}
	}
	
	private int excuteSolrCommand(String command){
		String solrServerUrl=ConfigUtil.getInstance().getSearchServerUrl();
		String commandUrl = solrServerUrl + "/dataimport?command="+command;
		URL postUrl= null;
		try {
			    postUrl= new URL(commandUrl);
				HttpURLConnection urlConnect=(HttpURLConnection)postUrl.openConnection();
				urlConnect.setRequestMethod("GET");
				urlConnect.connect();
				int responseCode= urlConnect.getResponseCode();
				log.info("Post the command  on ["+postUrl+"] and responseCode["+responseCode+"]!");
				if(responseCode != 200){
					log.warn("It's failed to post the command on ["+postUrl+"]!");
				}
				return responseCode;
			} catch (Exception e) {
				log.error("It's failed to post the command on ["+postUrl+"]!",e);
				return 500;
			}
	}
	/*
	 * (non-Javadoc)
	 * @see com.probiz.estore.solrsearch.service.SolrSearchService#fireRebuildFullIndex()
	 */
	public void fireRebuildFullIndex(){
		// 把后台生成索引的事件保存到数据库 定时刷新 前后台
		EventUtil.getInstance().fire(new SolrIndexRefreshEvent(this));		
	}
	
	
	/**
	 * 获得搜索服务
	 * @param request
	 * @return
	 */
	protected SolrServer getSolrServer() {
		try {
			CommonsHttpSolrServer commonsHttpSolrServer = new CommonsHttpSolrServer(ConfigUtil.getInstance().getSearchServerUrl());
			commonsHttpSolrServer.setConnectionTimeout(100);  //0.1秒
			commonsHttpSolrServer.setDefaultMaxConnectionsPerHost(100);
			commonsHttpSolrServer.setMaxTotalConnections(100);
			return commonsHttpSolrServer;
		} catch (Exception ex) {
			throw new RuntimeException(ex);
		}
	}
	/*
	 * (non-Javadoc)
	 * @see com.probiz.estore.solrsearch.service.SolrSearchService#searchByCriteria(com.probiz.estore.solrsearch.model.SolrSearchCriteria, com.probiz.estore.core.search.SearchCriteria)
	 */
	public List<IndexEntity> searchByCriteria(SolrSearchCriteria solrSearchCriteria,SearchCriteria searchCriteria) throws SolrServerException{
		List<IndexEntity> indexEntityList = new ArrayList<IndexEntity>();
		//--------------------start:搜索--------------------
		Integer currPage = searchCriteria.getPageNo();
		if(currPage < 1){
			currPage = 1;
		}
		SolrServer server = getSolrServer();
		SolrQuery query = new SolrQuery("*:*");
		StringBuffer buff = new StringBuffer();
		buff.append("field_entityTitle:(").append(solrSearchCriteria.getKeywords()).append(") OR field_description:(").append(solrSearchCriteria.getKeywords()).append(")")
		.append(" OR field_fullDescription:(").append(solrSearchCriteria.getKeywords()).append(")");
		query.set(CommonParams.Q, buff.toString());
		query.set(CommonParams.START, searchCriteria.getStartIdx());	
		query.set(CommonParams.ROWS, searchCriteria.getPageSize());
		query.set(CommonParams.SORT, "field_updateTime desc");
		query.set(HighlightParams.HIGHLIGHT, "true");
		query.set(HighlightParams.MAX_CHARS, 250);
		query.set(HighlightParams.SNIPPETS, 1);
		query.set(HighlightParams.FRAGSIZE, 250);
		query.set(HighlightParams.FIELDS, "field_entityTitle,field_description");
		QueryRequest qRequest = new QueryRequest(query);
		QueryResponse qr = qRequest.process(server);
		SolrDocumentList solDocList = qr.getResults();
		//--------------------end:搜索--------------------
		
		//--------------------start:注入--------------------
		for (int i = 0; i < solDocList.size(); i++) {
			SolrDocument d = solDocList.get(i);
			IndexEntity indexEntity = new IndexEntity();
			indexEntity.setIndexId((String) d.getFieldValue("field_indexId"));
			indexEntity.setIndexType((String) d.getFieldValue("field_indexType"));
			indexEntity.setEntityId(new Integer((String) d.getFieldValue("field_entityId")));
			if (d.getFieldValue("field_imageUrl") != null) {
				indexEntity.setImageUrl((String) d.getFieldValue("field_imageUrl"));
			}
			if (d.getFieldValue("field_updateTime") != null){
				Date updateTime = (Date)d.getFieldValue("field_updateTime");
				indexEntity.setUpdateTime(updateTime);
			}
			List<String> list = qr.getHighlighting().get(d.getFieldValue("field_indexId")).get("field_entityTitle");
			if (list != null && list.size() > 0){
				indexEntity.setEntityTitle(list.get(0));
			}else{
				indexEntity.setEntityTitle((String) d.getFieldValue("field_entityTitle"));
			}
			list = qr.getHighlighting().get(d.getFieldValue("field_indexId")).get("field_description");
			if (list != null && list.size() > 0){
				indexEntity.setDescription(list.get(0));
			}else{
				indexEntity.setDescription("");
			}
			indexEntityList.add(indexEntity);

		}
		//根据不同类型设置uri和目录名称
		for(IndexEntity entity: indexEntityList){
			if(IndexEntity.TYPE_PRODUCT.equals(entity.getIndexType())){
				Product product = productManager.getById(Integer.valueOf(entity.getEntityId()));
				if(null!=product){	
					String uri = productManager.getUriByProduct(product);
					entity.setUri(uri);
					entity.setCategoryName(product.getCategory().getCategoryName());
				}
			}else if(IndexEntity.TYPE_CONTENT.equals(entity.getIndexType())){
				Content content = contentManager.getById(Integer.valueOf(entity.getEntityId()));
				if(null!=content){	
					String uri = contentManager.getUriByContent(content);
					entity.setUri(uri);
					entity.setCategoryName(content.getCategory().getCategoryName());
				}
			}
		}
		//--------------------end:注入--------------------
		
		
		//--------------------start:返回--------------------
		searchCriteria.setTotalCount(solDocList.getNumFound());
		solrSearchCriteria.setQtime((long)qr.getQTime());
		//--------------------end:返回--------------------
		
		return indexEntityList;
	}
	
	public List<IndexEntity> searchByCriteriaForController(SolrSearchCriteria solrSearchCriteria,SearchCriteria searchCriteria) throws SolrServerException{
		if (searchCriteria.getPageNo() < 1)  //如果是翻页过前，就拿第一页就可以。
        {
            searchCriteria.changePaging(1, searchCriteria.getPageSize());
        }
	    List<IndexEntity> result = searchByCriteria(solrSearchCriteria, searchCriteria);
	    if (result == null|| result.size() == 0 )
	    {
	        if (searchCriteria.getTotalPageCount() > 0 && searchCriteria.getPageNo() > searchCriteria.getTotalPageCount()) //如果是翻页前，就拿最后一页就可以。
	        {
	            searchCriteria.changePaging(searchCriteria.getTotalPageCount(), searchCriteria.getPageSize());
	            result = searchByCriteria(solrSearchCriteria, searchCriteria);
	        }
	    }
		return result;
	}
}

